package com.wunu.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.wunu.base.BusinessException;
import com.wunu.base.Constant;
import com.wunu.base.PublicResultConstant;
import com.wunu.entity.Menu;
import com.wunu.entity.Role;
import com.wunu.entity.SmsVerify;
import com.wunu.service.*;
import com.wunu.entity.User;
import com.wunu.entity.UserToRole;
import com.wunu.mapper.UserMapper;
import com.wunu.util.*;

import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wunu kin
 * @since 2019-03-25
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private IUserToRoleService userToRoleService;
    @Autowired
    private IMenuService menuService;

    @Autowired
    private UserMapper mapper;


    @Autowired
    private ISmsVerifyService smsVerifyService;


    @Autowired
    private IRoleService roleService;

    @Override
//    @Cacheable(value = "UserToRole",keyGenerator="wiselyKeyGenerator")
    public User getUserByUserName(String username) {
        System.out.println("执行getUserByUserName方法了.....");
        EntityWrapper<User> ew = new EntityWrapper<>();
        ew.where("userName={0}", username);
        return this.selectOne(ew);
    }

    @Override
    public User getUserByMobile(String phone) {
        EntityWrapper<User> ew = new EntityWrapper<>();
        ew.eq("phone", phone);
        return this.selectOne(ew);
    }

    @Override
    public User register(User user, String  type) {
        user.setUserNo(GenerationSequenceUtil.generateUUID(type));
        user.setCreateTime(DateTimeUtil.formatDateTimetoString(new Date()));
        boolean result = this.insert(user);
        if (result) {
            UserToRole userToRole  = UserToRole.builder().userNo(user.getUserNo()).roleCode(user.getRoleCode()).build();
            userToRoleService.insert(userToRole);
        }
        return user;
    }

    @Override
    public Map<String, Object> getLoginUserAndMenuInfo(User user) {
        Map<String, Object> result = new HashMap<>();
        UserToRole userToRole = userToRoleService.selectByUserNo(user.getUserNo());
        user.setToken(JWTUtil.sign(user.getUserNo(), user.getPassword()));
        result.put("user",user);
        if(userToRole!=null) {
//        List<Menu> buttonList = new ArrayList<Menu>();
        //根据角色主键查询启用的菜单权限
        List<Menu> menuList = menuService.findMenuByRoleCode(userToRole.getRoleCode());
        List<Menu> retMenuList = menuService.treeMenuList(Constant.ROOT_MENU, menuList);
//        for (Menu buttonMenu : menuList) {
//            if(buttonMenu.getMenuType() == Constant.TYPE_BUTTON){
//                buttonList.add(buttonMenu);
//            }
//        }
        result.put("menuList",retMenuList);
//        result.put("buttonList",buttonList);
        }
        return result;
    }

    @Override
    public void deleteByUserNo(String userNo) throws Exception{
        User user = this.selectById(userNo);
        if (ComUtil.isEmpty(user)) {
            throw new BusinessException(PublicResultConstant.INVALID_USER);
        }
        EntityWrapper<UserToRole> ew = new EntityWrapper<>();
        ew.eq("userNo", userNo);
        userToRoleService.delete(ew);
        this.deleteById(userNo);
    }

    @Override
    public Page<User> selectPageByConditionUser(Page<User> userPage, String info, Integer[] status, String startTime, String endTime) {
        //注意！！ 分页 total 是经过插件自动 回写 到传入 page 对象
        return userPage.setRecords(mapper.selectPageByConditionUser(userPage, info,status,startTime,endTime));
    }
    @Override
    public Page<User> selectPageUser(Page<User> userPage, String info,  String ownerId,String userNo) {
        //注意！！ 分页 total 是经过插件自动 回写 到传入 page 对象
        return userPage.setRecords(mapper.selectPageUser(userPage, info,ownerId,userNo));
    } 
    

    @Override
    public Map<String, Object> checkAccountAndPasswd(JSONObject requestJson) throws Exception{
        //由于 @ValidationParam注解已经验证过mobile和passWord参数，所以可以直接get使用没毛病。
        String userName = requestJson.getString("userName");
        User user = this.selectOne(new EntityWrapper<User>().where("userName = {0} and status = 1",userName));
        if (ComUtil.isEmpty(user) || !BCrypt.checkpw(requestJson.getString("password"), user.getPassword())) {
            throw new BusinessException(PublicResultConstant.INVALID_USERNAME_PASSWORD);
        }
        return this.getLoginUserAndMenuInfo(user);
    }
    
    @Override
    public Map<String, Object> userInfo(String  userNo) throws Exception{
        //由于 @ValidationParam注解已经验证过mobile和passWord参数，所以可以直接get使用没毛病。
        User user = this.selectOne(new EntityWrapper<User>().where("userNo = {0} and status = 1",userNo));
        if (ComUtil.isEmpty(user)) {
            throw new BusinessException(PublicResultConstant.INVALID_USERNAME_PASSWORD);
        }
        return this.getLoginUserAndMenuInfo(user);
    }
    @Override
    public Map<String, Object> checkMobileAndCatcha(JSONObject requestJson) throws Exception {
        String phone = requestJson.getString("phone");
        if(!StringUtil.checkMobileNumber(phone)){
            throw new BusinessException(PublicResultConstant.MOBILE_ERROR);
        }
        User user = this.getUserByMobile(phone);
        //如果不是启用的状态
        if(!ComUtil.isEmpty(user) && user.getStatus() != Constant.ENABLE){
            throw new BusinessException("该用户状态不是启用的!");
        }
        List<SmsVerify> smsVerifies = smsVerifyService.getByMobileAndCaptchaAndType(phone,
                requestJson.getString("captcha"), SmsSendUtil.SMSType.getType(SmsSendUtil.SMSType.AUTH.name()));
        if(ComUtil.isEmpty(smsVerifies)){
            throw new BusinessException(PublicResultConstant.VERIFY_PARAM_ERROR);
        }
        if(SmsSendUtil.isCaptchaPassTime(smsVerifies.get(0).getCreateTime())){
            throw new BusinessException(PublicResultConstant.VERIFY_PARAM_PASS);
        }
        if (ComUtil.isEmpty(user)) {
            //设置默认密码
            User userRegister = User.builder().password(BCrypt.hashpw("123456", BCrypt.gensalt()))
                    .phone(phone).userName(phone).build();
            user =this.register(userRegister, Constant.RoleType.USER);
        }
        return this.getLoginUserAndMenuInfo(user);
    }

    @Override
    public User checkAndRegisterUser(User user,JSONObject requestJson) throws Exception {
    	 String type = "";
    	 Role role = roleService.selectById(user.getRoleCode());
        //可直接转为java对象,简化操作,不用再set一个个属性
        User userRegister = requestJson.toJavaObject(User.class);
        if(!StringUtil.checkMobileNumber(userRegister.getPhone())){
            throw new BusinessException(PublicResultConstant.MOBILE_ERROR);
        }
        if (!userRegister.getPassword().equals(requestJson.getString("repassword"))) {
            throw new BusinessException(PublicResultConstant.INVALID_RE_PASSWORD);
        }
		/*
		 * List<SmsVerify> smsVerifies =
		 * smsVerifyService.getByMobileAndCaptchaAndType(userRegister.getPhone(),
		 * requestJson.getString("captcha"),
		 * SmsSendUtil.SMSType.getType(SmsSendUtil.SMSType.REG.name()));
		 * if(ComUtil.isEmpty(smsVerifies)){ throw new
		 * BusinessException(PublicResultConstant.VERIFY_PARAM_ERROR); } //验证码是否过期
		 * if(SmsSendUtil.isCaptchaPassTime(smsVerifies.get(0).getCreateTime())){ throw
		 * new BusinessException(PublicResultConstant.VERIFY_PARAM_PASS); }
		 */
        if(!role.getRoleType().equals(Constant.RoleType.SYS_ASMIN_ROLE)) {
        	userRegister.setBusinessCode(user.getBusinessCode());
        	userRegister.setEntrprise(false);
        	type =Constant.RoleType.USER;
        }else {
        	userRegister.setBusinessCode(GenerationSequenceUtil.generateUUID("business"));
        	userRegister.setEntrprise(true);
        	type =Constant.RoleType.ADMIN;
        }
        userRegister.setParentId(user.getUserNo());
        userRegister.setPassword(BCrypt.hashpw(requestJson.getString("password"), BCrypt.gensalt()));
        //默认注册普通用户
        return this.register(userRegister,type);
    }

    @Override
    public User updateForgetPasswd(JSONObject requestJson) throws Exception {
        String phone = requestJson.getString("phone");
        if(!StringUtil.checkMobileNumber(phone)){
            throw new BusinessException(PublicResultConstant.MOBILE_ERROR);
        }
        if (!requestJson.getString("password").equals(requestJson.getString("rePassword"))) {
            throw new BusinessException(PublicResultConstant.INVALID_RE_PASSWORD);
        }
        User user = this.getUserByMobile(phone);
        roleService.getRoleIsAdminByUserNo(user.getUserNo());
        if(ComUtil.isEmpty(user)){
            throw new BusinessException(PublicResultConstant.INVALID_USER);
        }
        List<SmsVerify> smsVerifies = smsVerifyService.getByMobileAndCaptchaAndType(phone,
                requestJson.getString("captcha"), SmsSendUtil.SMSType.getType(SmsSendUtil.SMSType.FINDPASSWORD.name()));
        if(ComUtil.isEmpty(smsVerifies)){
            throw new BusinessException(PublicResultConstant.VERIFY_PARAM_ERROR);
        }
        if(SmsSendUtil.isCaptchaPassTime(smsVerifies.get(0).getCreateTime())){
            throw new BusinessException(PublicResultConstant.VERIFY_PARAM_PASS);
        }
        user.setPassword(BCrypt.hashpw(requestJson.getString("password"),BCrypt.gensalt()));
        this.updateById(user);
        return user;
    }

    @Override
    public void resetMobile(User currentUser, JSONObject requestJson) throws Exception {
        String newPhone = requestJson.getString("newPhone");
        if(!StringUtil.checkMobileNumber(newPhone)){
          throw  new BusinessException(PublicResultConstant.MOBILE_ERROR);
        }
        List<SmsVerify> smsVerifies = smsVerifyService.getByMobileAndCaptchaAndType(newPhone,
                requestJson.getString("captcha"), SmsSendUtil.SMSType.getType(SmsSendUtil.SMSType.MODIFYINFO.name()));
        if(ComUtil.isEmpty(smsVerifies)){
            throw  new BusinessException(PublicResultConstant.VERIFY_PARAM_ERROR);
        }
        if(SmsSendUtil.isCaptchaPassTime(smsVerifies.get(0).getCreateTime())){
            throw  new BusinessException(PublicResultConstant.VERIFY_PARAM_PASS);
        }
        currentUser.setPhone(newPhone);
        this.updateById(currentUser);
    }

    @Override
    public void resetPassWord(User currentUser, JSONObject requestJson) throws Exception {
        if (!requestJson.getString("password").equals(requestJson.getString("rePassword"))) {
            throw  new BusinessException(PublicResultConstant.INVALID_RE_PASSWORD);
        }
        if(!BCrypt.checkpw(requestJson.getString("oldPassword"),currentUser.getPassword())){
            throw  new BusinessException(PublicResultConstant.INVALID_USERNAME_PASSWORD);
        }
        currentUser.setPassword(BCrypt.hashpw(requestJson.getString("password"),BCrypt.gensalt()));
        this.updateById(currentUser);
    }

     public static void main(String[] args) {
		 System.out.println(BCrypt.hashpw("Kinfeng98", BCrypt.gensalt())); 
    	 System.out.println(GenerationSequenceUtil.generateUUID("menu"));
    	 
	}
     
     /**
      **合成二维码数据
      */
	@Override
	public Page<User> changePage(Page<User> page){
		long id  = 2;
		String name = "wunu";
		List<User> userliList = new ArrayList<User>();
		for (User user : page.getRecords()) {
			if("1".equals(user.getParentId())) {
				name = user.getName();
				id = user.getId();
			}
		 	JSONObject jsonObject = new JSONObject();
		 	jsonObject.put("name", name);
		 	jsonObject.put("uuid", user.getBusinessCode());
		 	jsonObject.put("bussinessNum", id);
		 	jsonObject.toJSONString();
		 	String codeString = Base64.encode(jsonObject.toJSONString().getBytes()).replace("=", "");
			user.setCode(codeString);
		 	userliList.add(user);
	} 
		return page.setRecords(userliList);
	}

}
